package xj.toolkit.netty.handler.codec.http.transformer;

import io.netty.handler.codec.http.FullHttpRequest;
import xj.toolkit.netty.handler.codec.http.HttpCommandCodeRegistry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @author hp
 *
 */
public class CodeDispatchTransformer implements HttpRequestTransformer, HttpCommandCodeRegistry {

	private static final Logger logger = LoggerFactory.getLogger(CodeDispatchTransformer.class);

	private RequestCodeGetter codeGetter = new RequestCodeGetter();

	private ConcurrentMap<String, HttpRequestTransformer> dispatch = new ConcurrentHashMap<String, HttpRequestTransformer>();

	public void addTransformer(String code, HttpRequestTransformer transformer) {
		dispatch.put(code, transformer);
	}

	public void setTransformers(Map<String, HttpRequestTransformer> transformers) {
		this.dispatch.clear();

		for (Map.Entry<String, HttpRequestTransformer> entry : transformers.entrySet()) {
			if (null != entry.getValue()) {
				this.dispatch.put(entry.getKey(), entry.getValue());
			}
		}
	}

	@Override
	public Object transform(FullHttpRequest request) {
		String code = codeGetter.transform(request);
		HttpRequestTransformer trans = dispatch.get(code);

		if (null != trans) {
			if (logger.isDebugEnabled()) {
				logger.debug("found transformer {} for code {}", trans, code);
			}
			return trans.transform(request);
		} else {
			if (logger.isDebugEnabled()) {
				logger.debug("!CAN NOT! found any transformer for code {}, just ignore.", code);
			}
			return null;
		}
	}

	public void register(String code, HttpRequestTransformer transformer) {
		dispatch.put(code, transformer);
	}

	public boolean unregister(String code, HttpRequestTransformer transformer) {
		return dispatch.remove(code, transformer);
	}

	public Map<String, String> getAllEntries() {
		Map<String, String> ret = new HashMap<String, String>();
		for (Map.Entry<String, HttpRequestTransformer> entry : this.dispatch.entrySet()) {
			ret.put(entry.getKey(), entry.getValue().toString());
		}

		return ret;
	}
}
